package com.yuanfeng.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yuanfeng.commoms.constant.CommonType;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.DateUtils;
import com.yuanfeng.commoms.util.ParseMapUtils;
import com.yuanfeng.commoms.util.ParseTokenUtils;
import com.yuanfeng.commoms.util.ResponseResult;
import com.yuanfeng.commoms.util.excel.ExcelsUtil;
import com.yuanfeng.commoms.util.querypage.PageUtils;
import com.yuanfeng.commoms.util.querypage.Query;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import com.yuanfeng.payment.dto.CardAmountDTO;
import com.yuanfeng.payment.dto.RechargeCardDTO;
import com.yuanfeng.payment.dto.ReturnCardBaseInfoDTO;
import com.yuanfeng.payment.entity.PayCardBaseEntity;
import com.yuanfeng.payment.entity.PayCardEntity;
import com.yuanfeng.payment.entity.PayCardInfoEntity;
import com.yuanfeng.payment.mapper.PayCardBaseMapper;
import com.yuanfeng.payment.mapper.PayCardInfoMapper;
import com.yuanfeng.payment.mapper.PayCardMapper;
import com.yuanfeng.payment.service.PayCardBaseService;
import com.yuanfeng.payment.vo.*;
import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.spring.annotation.GlobalTransactional;
import io.seata.tm.api.GlobalTransactionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 *
 */
@Service
public class PayCardBaseServiceImpl extends ServiceImpl<PayCardBaseMapper, PayCardBaseEntity>
    implements PayCardBaseService{

    @Autowired
    private PayCardMapper payCardMapper;

    @Autowired
    private PayCardInfoMapper payCardInfoMapper;
    @Override
    public ResponseResult queryDetail(ReturnCardBaseInfoDTO dto) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(dto.getToken());
        Map<String,Object> map=new HashMap();
        if (userInfo==null){
            userInfo=ParseTokenUtils.getPlatformUser(dto.getToken());
        }
        if (null != userInfo) {
            try {
                //将对象转换为map
                Map data = ParseMapUtils.beanToMap(dto);
                //分页查询数据
                IPage<PayCardBaseInfoVO> page = this.baseMapper.queryCardbaseInfoReport(new Query<PayCardBaseInfoVO>().getPage(data), dto);

                double money = this.baseMapper.queryNoRechargeMoney(dto);

                map.put("amoney",money);
                map.put("result",PageUtils.getPage(page));
                return ResponseResult.success(map);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult queryList(Map<String, Object> map) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(map.get("token").toString());

        if (null != userInfo) {
            //分页查询数据
            IPage<PayCardBaseVO> page = this.baseMapper.queryList(new Query<PayCardBaseVO>().getPage(map), map);

            double money = this.baseMapper.queryActivationNoRechargeMoney();

            map.put("amoney",money);
            map.put("result",PageUtils.getPage(page));
            return ResponseResult.success(map);

        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult queryCardConsumeExcel(CardAmountDTO param) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(param.getToken());
        if (null != userInfo) {
            List<CardIncomeListVO> page = this.baseMapper.selectCardConsumeExcel(param);
            String[] headers = {"商户订单id", "用户id", "昵称", "金额", "标题", "描述",
                    "创建时间", "类型", "付款状态", "充值的付款方式", "支付金额", "支付方式", "退款金额"};
            List<Map<String, String>> list = Lists.newArrayList();
            for (CardIncomeListVO cardAmountList : page) {
                HashMap<String, String> map = Maps.newHashMap();
                map.put("商户订单id", cardAmountList.getOrderId());
                map.put("用户id", cardAmountList.getUserId());
                map.put("昵称", cardAmountList.getUserNickname());
                map.put("金额", cardAmountList.getRecordMoney() + "");
                map.put("标题", cardAmountList.getRecordTitle());
                map.put("描述", cardAmountList.getRecordDesc());
                map.put("创建时间", cardAmountList.getRecordTime() == null ? "" :  DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss",cardAmountList.getRecordTime()));
                if (cardAmountList.getTradeTypeId() == null){
                    cardAmountList.setTradeTypeId(-1);
                }
                if (cardAmountList.getRecordStatus() == null){
                    cardAmountList.setRecordStatus(-1);
                }
                    switch (cardAmountList.getTradeTypeId()) {
                        case 1:
                            map.put("类型", "购物");
                            break;
                        case 2:
                            map.put("类型", "转账");
                            break;
                        case 3:
                            map.put("类型", "充值");
                            break;
                        case 4:
                            map.put("类型", "提现");
                            break;
                        case 5:
                            map.put("类型", "退款");
                            break;
                        case 10:
                            map.put("类型", "佣金");
                            break;
                        case 11:
                            map.put("类型", "结算");
                            break;
                        case -1:
                            map.put("类型", "");
                            break;
                    }
                    switch (cardAmountList.getRecordStatus()) {
                        case 1:
                            map.put("付款状态", "待付款");
                            break;
                        case 2:
                            map.put("付款状态", "已付款");
                            break;
                        case 3:
                            map.put("付款状态", "待发货");
                            break;
                        case 4:
                            map.put("付款状态", "已发货");
                            break;
                        case 5:
                            map.put("付款状态", "已签收");
                            break;
                        case 6:
                            map.put("付款状态", "确认收货");
                            break;
                        case 7:
                            map.put("付款状态", "取消");
                            break;
                        case -1:
                            map.put("付款状态", "");
                            break;
                    }
                map.put("充值的付款方式", cardAmountList.getDepositPayChannel() == null ? "" : cardAmountList.getDepositPayChannel().toString());
                map.put("支付金额", cardAmountList.getTradePaymentRechargeCard() + "");
                map.put("支付方式", cardAmountList.getPayCode() + "");
                map.put("退款金额", cardAmountList.getOrderRefundAmount() == null ? "0.00" : cardAmountList.getOrderRefundAmount().toString());
                list.add(map);
            }

            // excel文件名
            Map<String/* 此处的key为每个sheet的名称，一个excel中可能有多个sheet页 */, List<Map<String/* 此处key对应每一列的标题 */, String>>/*
             * 该list为每个sheet页的数据
             */> map = Maps.newHashMap();
            map.put("充值消费卡支出", list);
            String url = ExcelsUtil.createExcel(headers, map, new int[]{0}/* 此处数组为需要合并的列，可能有的需求是只需要某些列里面相同内容合并 */);
            return ResponseResult.success(url);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult queryCardConsume(CardAmountDTO param) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(param.getToken());
        if (null != userInfo) {
            try {
                //将对象转换为map
                Map data = ParseMapUtils.beanToMap(param);
                //分页查询数据
                IPage<CardIncomeListVO> page = this.baseMapper.selectCardConsume(new Query<CardIncomeListVO>().getPage(data), param);
                BigDecimal totalAmount = this.baseMapper.selectCardConsumeAmount(param);

                Integer returnFlag = 0;
                for (CardIncomeListVO e : page.getRecords()) {
                    if (CommonType.payType.CARD_AND_ALIPAY_PAYMENT.getCode().equals(e.getPayCode())
                            || CommonType.payType.CARD_AND_WECHAT_PAYMENT.getCode().equals(e.getPayCode())) {
                        totalAmount = totalAmount.subtract(e.getTradeThirdPartyAmount());
                    } else {
                        e.setTradePaymentRechargeCard(e.getRecordMoney());
                    }
                    Integer virtualGoods = e.getVirtualGoods();
                    Integer orderIsShopTake = e.getOrderIsShopTake();
                    if( null != orderIsShopTake && 1 == orderIsShopTake){
                        e.setOrderType(3);
                    }else{
                        if(null != virtualGoods && 0 == virtualGoods){
                            e.setOrderType(2);
                            e.setPastDue(e.getPastDue());
                            e.setIsCancel(e.getIsCancel());
                        }else{
                            e.setOrderType(1);
                        }
                    }
                    Integer returnStatus =e.getOrderReturnStatus()==null?0:Integer.valueOf(e.getOrderReturnStatus()) ;
                    Integer refundStatus = e.getOrderRefundStatus()==null?0:Integer.valueOf(e.getOrderRefundStatus());
                    if (2 == returnStatus || 2 == refundStatus) {
                        BigDecimal returnAmount=null;
                        if(e.getOrderRefundAmount()==null){
                            returnAmount = BigDecimal.valueOf(0);
                        }else{
                            returnAmount = e.getOrderRefundAmount();
                        }

                        BigDecimal orderAmount = e.getOrderPaymentAmount();
                        if (orderAmount.compareTo(returnAmount) > 0) {
                            returnFlag = 2;
                        } else if ((orderAmount.compareTo(returnAmount) == 0)) {
                            returnFlag = 1;
                        }
                    }
                    e.setReturnFlag(returnFlag);
                    if(0 != returnStatus && 0 != refundStatus){
                        e.setIsExistReturn("1");
                    }else{
                        e.setIsExistReturn("0");
                    }

                }
                Map<String, Object> map = new HashMap<>();
                map.put("totalAmount", totalAmount);
                map.put("currPage", PageUtils.getPage(page).getCurrPage());
                map.put("pageSize", PageUtils.getPage(page).getPageSize());
                map.put("list", PageUtils.getPage(page).getList());
                map.put("totalCount", PageUtils.getPage(page).getTotalCount());
                map.put("totalPage", PageUtils.getPage(page).getTotalPage());

                return ResponseResult.success(map);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult queryCardAmountListExcel(CardAmountDTO cardAmountQueryParam) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(cardAmountQueryParam.getToken());
        if (null != userInfo) {
            List<CardAmountListVO> cardAmountLists = this.baseMapper.queryCardAmountListExcel(cardAmountQueryParam);
            String[] headers = {"购物卡卡号", "购物卡密码", "购物卡面额", "领卡人账号", "卡片描述", "有效时间", "失效时间"};
            List<Map<String, String>> list = Lists.newArrayList();
            for (CardAmountListVO cardAmountList : cardAmountLists) {
                HashMap<String, String> map = Maps.newHashMap();
                map.put("购物卡卡号", cardAmountList.getCardCode());
                map.put("购物卡密码", cardAmountList.getCardPassword());
                map.put("购物卡面额", cardAmountList.getCardMoney());
                map.put("领卡人账号", cardAmountList.getUserAccount());
                map.put("卡片描述", cardAmountList.getCardDesc());
                map.put("有效时间", DateUtils.dateTime(cardAmountList.getCardStartTime()));
                map.put("失效时间", DateUtils.dateTime(cardAmountList.getCardEndTime()));
                list.add(map);
            }

            // excel文件名
            Map<String/* 此处的key为每个sheet的名称，一个excel中可能有多个sheet页 */, List<Map<String/* 此处key对应每一列的标题 */, String>>/*
             * 该list为每个sheet页的数据
             */> map = Maps.newHashMap();
            map.put("测试合并数据", list);
            String url = ExcelsUtil.createExcel(headers, map, new int[]{0}/* 此处数组为需要合并的列，可能有的需求是只需要某些列里面相同内容合并 */);
            return ResponseResult.success(url);
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    public ResponseResult queryCardAmountList(CardAmountDTO cardAmountQueryParam) {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(cardAmountQueryParam.getToken());
        if (null != userInfo) {
            try {
                //将对象转换为map
                Map data = ParseMapUtils.beanToMap(cardAmountQueryParam);
                //分页查询数据
                IPage<CardAmountListVO> page = this.baseMapper.queryCardAmountList(new Query<CardAmountListVO>().getPage(data), cardAmountQueryParam);
                BigDecimal totalAmount = this.baseMapper.selectCardAmount(cardAmountQueryParam);
                Map<String, Object> map = new HashMap<>();
                map.put("totalAmount", totalAmount);
                map.put("data", PageUtils.getPage(page));
                return ResponseResult.success(map);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }

    @Override
    @GlobalTransactional(rollbackFor = Exception.class)
    public ResponseResult check(RechargeCardDTO checkRechargeCardRequest) throws TransactionException {
        UserInfoVO userInfo = ParseTokenUtils.getPlatformUser(checkRechargeCardRequest.getToken());
        if (null != userInfo) {
            Map<Object, Object> map = new HashMap<Object, Object>();
            map.put("totalPrice", checkRechargeCardRequest.getTotalPrice());
            map.put("startCard", checkRechargeCardRequest.getStartCard());
            map.put("finishCard", checkRechargeCardRequest.getFinishCard());
            map.put("finishTime", checkRechargeCardRequest.getFinishTime());
            map.put("startTime", checkRechargeCardRequest.getStartTime());
            PayCardEntity card = payCardMapper.selectOne(new LambdaQueryWrapper<PayCardEntity>()
                    .eq(PayCardEntity::getId, checkRechargeCardRequest.getStartCard()));
            if(card == null){
                return ResponseResult.fail(BizCodeEnume.CARD_IS_NUll);
            }
            Date s = card.getEtime();

            if (s != null) {
                return ResponseResult.fail(BizCodeEnume.UPDATE_RECHARGE_CARD_ERROP.getCode(), BizCodeEnume.UPDATE_RECHARGE_CARD_ERROP.getMsg());
            }
            Integer cardCount = payCardMapper.updateRechargeCardPort(map);
            List<PayCardInfoVO> cardInfo = null;
            PayCardBaseVO baseResult = new PayCardBaseVO();
            baseResult.setCardDesc(checkRechargeCardRequest.getCardDesc());
            baseResult.setCardEndTime(checkRechargeCardRequest.getFinishTime());
            baseResult.setCardName(checkRechargeCardRequest.getTotalPrice() + "元");
            baseResult.setCardNum(
                    Integer.parseInt(checkRechargeCardRequest.getFinishCard()) - Integer.parseInt(checkRechargeCardRequest.getStartCard()) + 1 + "");
            baseResult.setCardPrize("{\"m\":" + checkRechargeCardRequest.getTotalPrice() + "}");
            baseResult.setCardStartTime(checkRechargeCardRequest.getStartTime());
            if (cardCount > 0) {
                cardInfo = payCardMapper.queryPayBaseParam(map);
                try {
                    Integer cardBase = this.baseMapper.insetPayCardBase(baseResult);
                    if (cardInfo.size() > 0) {
                        for (PayCardInfoVO payCardInfoResult : cardInfo) {
                            payCardInfoResult.setCardId(baseResult.getId() + "");
                            PayCardInfoEntity payCardInfoResult1 = payCardInfoMapper.selectOne(new LambdaQueryWrapper<PayCardInfoEntity>()
                                                                  .eq(PayCardInfoEntity::getCardCode,payCardInfoResult.getCardCode()));
                            if (payCardInfoResult1 != null) {
                                payCardInfoMapper.updatePayCardInfoBase(payCardInfoResult);
                            } else {
                                List<PayCardInfoVO> cardInfo2 = new ArrayList<>();
                                cardInfo2.add(payCardInfoResult);
                                payCardInfoMapper.insetPayCardInfoBase(cardInfo2, baseResult.getId());
                            }
                        }
                    }
                } catch (Exception e) {
                    GlobalTransactionContext.reload(RootContext.getXID()).rollback();
                    return ResponseResult.fail(BizCodeEnume.OPERATION_FAILED);
                }
            } else {
                return ResponseResult.fail(BizCodeEnume.UPDATE_RECHARGE_CARD_ERROP.getCode(), BizCodeEnume.UPDATE_RECHARGE_CARD_ERROP.getMsg());
            }
            return ResponseResult.success();
        }
        return ResponseResult.fail(BizCodeEnume.TOKEN_IS_ILLEGAL);
    }
}




